package com.yzr.demo01;

import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.IntegerAssert;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

@RestController
@Slf4j
public class UserDemo {
    private static final ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(()->null);

    @GetMapping("wrong")
    public Map wrong(@RequestParam("userId") Integer userId){
        Map result;
        try {
            String before = Thread.currentThread().getName()+":"+currentUser.get();
            currentUser.set(userId);
            String after = Thread.currentThread().getName()+":"+currentUser.get();
            result = new HashMap();
            result.put("before",before);
            result.put("after",after);
        } finally {
            currentUser.remove();
        }
        return result;
    }

    //线程个数
    private static int THREAD_COUNT = 10;
    //总元素数量
    private static int ITEM_COUNT = 1000;
    private ConcurrentHashMap<String,Long> getData(int count){
//        LongStream longStream = LongStream.rangeClosed(1, count);
//        Stream<Long> boxed = longStream.boxed();
        return LongStream.rangeClosed(1,count)
                .boxed()
                .collect(Collectors.toConcurrentMap((i)-> UUID.randomUUID().toString(), Function.identity(),(o1,o2)->o1,ConcurrentHashMap::new));
    }

    @GetMapping("wrong2")
    public String wrong2() throws InterruptedException {
        ConcurrentHashMap<String,Long> concurrentHashMap = getData(ITEM_COUNT-100);
        //初始900个元素
        log.info("init size:{}",concurrentHashMap.size());
        ForkJoinPool forkJoinPool = new ForkJoinPool(THREAD_COUNT);
        forkJoinPool.execute(()-> IntStream.rangeClosed(1,10).parallel().forEach(i->{
            synchronized (concurrentHashMap){
                int gap = ITEM_COUNT - concurrentHashMap.size();
                log.info("gap size :{}",gap);
                //补充元素
                concurrentHashMap.putAll(getData(gap));

                //++
            }
        }));
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);
        log.info("init size:{}",concurrentHashMap.size());
        return "OK";
    }

    @GetMapping("wrong3")
    public String wrong3() throws InterruptedException {
        ConcurrentHashMap<String,LongAdder> concurrentHashMap = new ConcurrentHashMap<>(10);
        concurrentHashMap.computeIfAbsent("11",__->new LongAdder()).increment();
        return "OK";
    }

    @GetMapping("wrong4")
    public String wrong4() throws InterruptedException {
        ConcurrentHashMap<String, Long> data = getData(10);
        List<Integer> collect = IntStream.rangeClosed(1, 10).boxed().toList();
//        IntStream.rangeClosed(1,100).parallel().forEach(__ -> );
        return "OK";
    }
}
